import { isObject } from '@/utils/is'
import { Icon } from '@vicons/utils'
import { h, Component } from 'vue'
import axios from 'axios'
import { storage } from '@/utils/Storage'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import { getAppEnvConfig } from '@/utils/env'
import { message } from 'ant-design-vue'
import JSEncrypt from 'jsencrypt/bin/jsencrypt'
// import { urlToHttpOptions } from 'url'

/**
 * 判断是否 url
 * */
export function isUrl(url: string) {
  return /(^http|https:\/\/)/g.test(url)
}

/**
 * render 图标
 * */
export function renderIcon(icon: Component | string) {
  if (typeof icon === 'string') {
    return () => h('img', { src: icon, style: 'width: 20px;padding-top: 4px;' })
  }
  return () => h(Icon, null, { default: () => h(icon) })
}

/**
 * 深度合并
 */
export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
  let key: string
  for (key in target) {
    src[key] = isObject(src[key]) ? deepMerge(src[key], target[key]) : (src[key] = target[key])
  }
  return src
}

/**
 * 判断是否有值（暂存）
 */
export function hasValue(value: any) {
  if (value === 0 || (value && value !== 'null') || (Array.isArray(value) && value.length)) {
    return true
  }
  return false
}

/**
 * 将对象添加当作参数拼接到URL上面
 * @param baseUrl 需要拼接的url
 * @param obj 参数对象
 * @returns {string} 拼接后的对象
 * 例子:
 *  let obj = {a: '3', b: '4'}
 *  setObjToUrlParams('www.baidu.com', obj)
 *  ==>www.baidu.com?a=3&b=4
 */
export function setObjToUrlParams(baseUrl: string, obj: object): string {
  let parameters = ''
  let url = ''
  for (const key in obj) {
    parameters += key + '=' + encodeURIComponent(obj[key]) + '&'
  }
  parameters = parameters.replace(/&$/, '')
  if (/\?$/.test(baseUrl)) {
    url = baseUrl + parameters
  } else {
    url = baseUrl.replace(/\/?$/, '?') + parameters
  }
  return url
}

/** 随机生成固定位数或者一定范围内的字符串数字组合
 * @param {Number} min 范围最小值
 * @param {Number} max 范围最大值，当不传递时表示生成指定位数的组合
 * @param {String} charStr指定的字符串中生成组合
 * @returns {String} 返回字符串结果
 * */
export function randomRange(min?: number, max?: number, charStr = '') {
  let returnStr = '', //返回的字符串
    range //生成的字符串长度

  //随机生成字符
  const autoGetStr = function () {
    const charFun = function () {
      const n = Math.floor(Math.random() * 62)
      if (n < 10) {
        return n //1-10
      } else if (n < 36) {
        return String.fromCharCode(n + 55) //A-Z
      }
      return String.fromCharCode(n + 61) //a-z
    }
    while (returnStr.length < range) {
      returnStr += charFun()
    }
  }

  //根据指定的字符串中生成组合
  const accordCharStrGet = function () {
    for (let i = 0; i < range; i++) {
      const index = Math.round(Math.random() * (charStr.length - 1))
      returnStr += charStr.substring(index, index + 1)
    }
  }
  if (typeof min === 'undefined') {
    min = 10
  }
  if (typeof max === 'string') {
    charStr = max
  }
  range = max && typeof max === 'number' ? Math.round(Math.random() * (max - min)) + min : min

  if (charStr) {
    accordCharStrGet()
  } else {
    autoGetStr()
  }
  return returnStr
}
/** 文件大小转换为kb
 * */
export function GetFileSize(fileByte) {
  if (fileByte) {
    const fileSizeByte = fileByte
    let fileSizeMsg = ''
    if (!fileByte) {
      return fileSizeMsg
    }
    if (fileSizeByte < 1048576) {
      fileSizeMsg = (fileSizeByte / 1024).toFixed(2) + 'KB'
    } else if (fileSizeByte === 1048576) {
      fileSizeMsg = '1MB'
    } else if (fileSizeByte > 1048576 && fileSizeByte < 1073741824) {
      fileSizeMsg = (fileSizeByte / (1024 * 1024)).toFixed(2) + 'MB'
    } else if (fileSizeByte > 1048576 && fileSizeByte === 1073741824) {
      fileSizeMsg = '1GB'
    } else if (fileSizeByte > 1073741824 && fileSizeByte < 1099511627776) {
      fileSizeMsg = (fileSizeByte / (1024 * 1024 * 1024)).toFixed(2) + 'GB'
    } else {
      fileSizeMsg = '文件超过1TB'
    }
    return fileSizeMsg
  }
  return ''
}

// 把常量数组转换成{value:label}
export function APPFN_SET_VALUE_LABEL(arr) {
  const obj = {}
  for (let i = 0; i < arr.length; i++) {
    const item = arr[i]
    obj[item.value] = item.label
  }
  return obj
}

// 把常量数组转换成{name:value}
export function APPFN_SET_NAME_VALUE(arr) {
  const obj = {}
  for (let i = 0; i < arr.length; i++) {
    const item = arr[i]
    obj[item.name] = item.value
  }
  return obj
}

// 把常量数组转换成Map
export function APPFN_SET_VALUE_MAP(arr) {
  const obj = {}
  for (let i = 0; i < arr.length; i++) {
    const item = arr[i]
    obj[item.value] = item
  }
  return obj
}

// 是否CTMS配置
export function isConfig() {
  return window.location.href.includes('/operation/')
}
// 是否药房
export function isPharmacy() {
  return window.location.pathname.indexOf('/pharmacy/') === 0
}

// 分解文件
export function splitFile(fileName) {
  const index = fileName.lastIndexOf('.') + 1
  return {
    fileName: index < 1 ? fileName : fileName.substring(0, index - 1),
    fileType: fileName.substring(index)
  }
}

// 转换文件流
const FILE_NAME_REGX: any = /.*filename="([\w%-_.]+(.\w+)?)"/
export async function downloadFile(url) {
  await axios
    .get(url, {
      responseType: 'blob',
      headers: {
        'yootrial-account': 0,
        'yootrial-app': 0,
        'yootrial-signature': 0,
        'yootrial-timestamp': Date.now(),
        Authorization: 'Bearer' + storage.get(ACCESS_TOKEN)
      }
    })
    .then((res) => {
      const url = window.URL.createObjectURL(new Blob([res.data]))
      const link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      const contentDisposition = res.headers['content-disposition']
      const fileName = FILE_NAME_REGX.test(contentDisposition)
        ? FILE_NAME_REGX.exec(contentDisposition)[1]
        : 'fileName.txt'
      link.download = decodeURI(fileName)
      document.body.appendChild(link)
      link.click()
      // 释放URL对象所占资源
      window.URL.revokeObjectURL(url)
      // 用完即删
      document.body.removeChild(link)
    })
    .catch(() => {})
}

//转换文件流post请求
const FILE_NAME_REGX2: any = /.*filename=([\w%-_.]+(.\w+)?)/
export async function downloadFilePost(url, params, callback?) {
  callback = callback || function () {}
  await axios
    .post(url, params, {
      responseType: 'blob',
      headers: {
        'yootrial-account': 0,
        'yootrial-app': 0,
        'yootrial-signature': 0,
        'yootrial-timestamp': Date.now(),
        Authorization: 'Bearer' + storage.get(ACCESS_TOKEN)
      }
    })
    .then((res) => {
      const url = window.URL.createObjectURL(new Blob([res.data]))
      const link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      const contentDisposition = res.headers['content-disposition']
      const fileName = FILE_NAME_REGX2.test(contentDisposition)
        ? FILE_NAME_REGX2.exec(contentDisposition)[1]
        : 'fileName.txt'
      link.download = decodeURI(fileName)
      document.body.appendChild(link)
      link.click()
      // 释放URL对象所占资源
      window.URL.revokeObjectURL(url)
      // 用完即删
      document.body.removeChild(link)
      callback()
    })
    .catch(() => {
      callback()
    })
}

// 文件流转换
export function fileConversion(res, callback?, type = 1) {
  const blobData = new Blob([res.data])
  const fileReader: any = new FileReader() // 创建读取文件对象
  fileReader.addEventListener('loadend', function () {
    try {
      const resData = JSON.parse(fileReader.result)
      if (resData && typeof resData === 'object' && !resData.data) {
        message.error(resData.msg)
      }
    } catch (error) {
      const url = window.URL.createObjectURL(blobData)
      const link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      let fileNameRegx = FILE_NAME_REGX
      if (type === 2) {
        fileNameRegx = FILE_NAME_REGX2
      }
      const contentDisposition = res.headers['content-disposition']
      const fileName = fileNameRegx.test(contentDisposition) ? fileNameRegx.exec(contentDisposition)[1] : 'fileName.txt'
      link.download = decodeURI(fileName)
      document.body.appendChild(link)
      link.click()
      // 释放URL对象所占资源
      window.URL.revokeObjectURL(url)
      // 用完即删
      document.body.removeChild(link)
      typeof callback === 'function' && callback()
    }
  })
  fileReader.readAsText(blobData, 'utf-8')
}

/**
 * 获取数据类型
 * @param {} obj
 * @return boolean | number | string | function | array | date | regExp | undefined | null | object
 */
export function getType(obj) {
  const toString = Object.prototype.toString
  const map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object'
  }
  return map[toString.call(obj)]
}

/**
 * 格式化金额
 */
export function formatPrice(price) {
  if (getType(price) !== 'number') {
    return price
    // throw new Error('金额非数字，无法转换')
  }

  const options = {
    style: 'currency', // 用于货币格式
    currency: 'CNY'
  }

  return price.toLocaleString('zh-CN', options) // ¥999,999.00
}
// 文件预览
export function previewFile(file, getUrl = false, customApi?) {
  const orgId = storage.get('ORGINFO') ? storage.get('ORGINFO').orgId : ''
  const { VITE_GLOB_PRIVIEW_FILE_URL } = getAppEnvConfig()
  const timestamp = new Date().getTime()
  const baseApi = `/Rest/doc/file/filePreview?timestamp=${timestamp}&docId=${file.uid}&orgId=${orgId}&fileName=${file.fileName}`
  const fileUrl = `${VITE_GLOB_PRIVIEW_FILE_URL}${customApi ? customApi : baseApi}`
  if (getUrl) {
    return 'https://ow365.cn/?i=17462&ssl=1&furl=' + fileUrl
  }
  window.open('/filepreview?furl=' + encodeURIComponent(fileUrl), '_blank')
  // window.open('https://ow365.cn/?i=17462&ssl=1&furl=' + fileUrl, '_blank')
}

export function getAppInfo() {
  const orgInfo = storage.get('ORGINFO')
  const appId = sessionStorage.getItem('__appId')
  const appData = orgInfo.appList.find((item) => (item.appId = appId))
  if (appData) {
    return appData
  }
  throw new Error('getAppInfo 没有找到应用信息')
}

export function setCache(type, info) {
  info = typeof info === 'object' ? JSON.stringify(info) : info
  return localStorage.setItem(type, info)
}

export function getCache(type) {
  let obj: any = localStorage.getItem(type) || '{}'
  try {
    obj = JSON.parse(obj)
  } catch (e) {
    obj = {}
  }
  return obj
}

// 下载文件

export function blobFileDownload(blobData, fileName?, callback = function () {}, type = 2) {
  const url = window.URL.createObjectURL(new Blob([blobData.data]))

  const link = document.createElement('a')
  link.style.display = 'none'
  link.href = url

  fileName = fileName || 'file'
  const contentDisposition = blobData.headers['content-disposition']
  let fileNameRegx = FILE_NAME_REGX2
  if (type === 1) {
    fileNameRegx = FILE_NAME_REGX
  }
  if (contentDisposition) {
    fileName = fileNameRegx.exec(contentDisposition)[1]
  }

  link.download = decodeURI(fileName)
  document.body.appendChild(link)
  link.click()
  // 释放URL对象所占资源
  window.URL.revokeObjectURL(url)
  // 用完即删
  document.body.removeChild(link)
  callback()
}
// pdf文件预览直接打开
export function blobFilePDFPreview(blobData) {
  const url = window.URL.createObjectURL(new Blob([blobData.data], { type: 'application/pdf' }))
  window.open(url)
}
/**
 * 跨页导出
 * @param currentPageKeys 当前页列表所有key  []
 * @param selectedKeys 当前页选中的key  []
 * @param allSelectedKeys 历史所有的key  []
 * return 跨页导出key集合 []
 */
export function crossPageExport(currentPageKeys: any, selectedKeys: any, allSelectedKeys: any) {
  const noSelectKeys = currentPageKeys.filter((item) => {
    return !selectedKeys.includes(item)
  })
  let selectKeys = [].concat(allSelectedKeys, selectedKeys)
  selectKeys = [...new Set(selectKeys)]
  return selectKeys
    .map((item) => {
      if (noSelectKeys.includes(item)) {
        return ''
      }
      return item
    })
    .filter((item) => item)
}

// 解析试验号前缀
export function getShortSubjectNumber(number, ruleItemFixedPrefix, type) {
  if (!ruleItemFixedPrefix || !number) {
    return number
  }
  if (type === 'screenNumber') {
    if (!ruleItemFixedPrefix[1]) {
      return number
    }
    return number.replaceAll(ruleItemFixedPrefix[1] + '-', '')
  }
  if (type === 'testNumber') {
    if (!ruleItemFixedPrefix[2]) {
      return number
    }
    return number.replaceAll(ruleItemFixedPrefix[2] + '-', '')
  }
  return number
}

// 设置入组率
export function setSubjectGroupPercentage(num) {
  if (num === 0) {
    return 0
  }
  if (num < 1) {
    return 1
  }
  return Math.floor(num)
}

// 获取姓名的缩写
export const getNameShort = (name, type): string => {
  if (!name) {
    return ''
  }
  const arr = name.split('')
  if (type === 'first') {
    return arr[0]
  }
  return arr[arr.length - 1]
}
// 数字转中文
export const toChineseNum = (num: number) => {
  const _num = num
  const chnNumChar = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
  const chnUnitChar = ['', '十', '百', '千']
  let strIns = '',
    chnStr = ''
  let unitPos = 0
  let zero = true
  while (num > 0) {
    const v = num % 10
    if (v === 0) {
      if (!zero) {
        zero = true
        chnStr = chnNumChar[v] + chnStr
      }
    } else {
      zero = false
      strIns = chnNumChar[v]
      strIns += chnUnitChar[unitPos]
      chnStr = strIns + chnStr
    }
    unitPos++
    num = Math.floor(num / 10)
  }
  if (_num < 20) {
    chnStr = chnStr.replace('一十', '十')
  }
  return chnStr
}

// 深拷贝
export const copyObj = (obj = {}) => {
  //变量先置空
  let newobj: any = null

  //判断是否需要继续进行递归
  if (typeof obj === 'object' && obj !== null) {
    newobj = obj instanceof Array ? [] : {} //进行下一层递归克隆
    for (const i in obj) {
      newobj[i] = copyObj(obj[i])
    }
  } else {
    //如果不是对象直接赋值
    newobj = obj
  }
  return newobj
}

// 是否平台管理-角色管理
export function isPlatform() {
  return window.location.href.includes('/config/platform/role')
}

// 自动滚动到表单第一个校验失败处
export const scrollToFirstError = () => {
  document.querySelector('.ant-form-item-has-error')?.scrollIntoView({ behavior: 'smooth', block: 'center' })
}

// 下拉选择框挂载器
export const getPopupContainer: any = (targetElement, parentQuery = '.ant-form') => {
  const parentNode = targetElement.closest(parentQuery)
  if (parentNode) {
    return parentNode
  }
  return document.body
}

// 加密
const publicKey = `MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/fsWFKkpeAcwiFiFD312ybdjBscRDk28tuP70vUJdpKXnbDow/wrmdQiGduGhwTsQgxpiJki+zLS1jZfkuxeJbMgwOFwZTR9BOwxm9PSoQ8Plz3uD2oj8G2bAIegUbbNi8mTY+HDD4sPUIHrNy+PHEO9yzyYYBmStFF/va/xQ6QIDAQAB`

export function encrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey) // 设置公钥
  return encryptor.encrypt(txt) // 对需要加密的数据进行加密
}
